/*
 * @Author: quit
 * @Date: 2021-12-30 15:06:29
 * @LastEditTime: 2022-01-15 11:27:13
 * @Descripttion: topo功能事件总线
 */
import Vue from 'vue'
import { deepCopy } from '@/utils/index'
// import { ToPoAdd } from '@/api/BotRequest'
import jsonData from '@/assets/ToPoData/topo-data.json'

const state = {
    appPegeData: null,
    topoData: {
        name: '--',
        layer: {
            backColor: '',
            backgroundImage: '',
            widthHeightRatio: '',
            width: 1600,
            height: 900
        },
        // ToPo Tools列表
        components: []
    }, // 当前场景的组态数据
    selectedIsLayer: true, // 当前选择的是不是layer层
    selectedComponent: null, // 当前选择的单个组件--仅仅当只有一个组件选中有效，当有多个组件选中，则置为null
    selectedComponents: [], // 当前选择的组件--只存identifier
    selectedComponentMap: {}, // 当前选择的组件--key=identifier，本数据和selectedComponents同步，主要用于渲染判断
    copySrcItems: [], // 当前是否使用了CTRL+C命令
    copyCount: 0, // copy计数，对于同一个复制源，每次复制后计数+1
    undoStack: [], // 操作记录数组
    redoStack: [], //
    selectedValue: 100 // 显示百分比
}

const mutations = {
    /**
     * @description: 获取当前项目ID与页面ID
     */
    setAppPageData(state, data) {
        state.appPegeData = data
    },
    /**
     * @description: 命令分发
     * @param {*} command 传入载荷,命令对象
     */
    execute(state, command) {
        // 暂时不做参数校验
        // 在这里分发命令--这里暂时先用switch分发，应该用表格分发
        let component = command.component
        // let resId = null
        switch (command.op) {
            case 'add':
                // 添加时调用后台接口给当前组件赋值并
                component.name = component.type + state.topoData.components.length
                component.style.visible = true
                component.style.transform = 0 // 旋转
                component.style.borderWidth = component.style.borderWidth ? component.style.borderWidth : 0
                component.style.borderStyle = component.style.borderStyle ? component.style.borderStyle : 'solid'
                component.style.borderColor = component.style.borderColor ? component.style.borderColor : '#ccccccff'
                component.style.fontFamily = 'Arial'
                // ;(async() => {
                //     let obj = {}
                //     const { data } = await ToPoAdd(obj)
                //     resId = data.id
                //     console.log(resId)
                // })()
                // console.log(resId)
                // component.identifier = resId
                console.log(component)
                state.topoData.components.push(component)
                break
            case 'del':
                var keys = []
                for (let i = 0; i < state.topoData.components.length; i++) {
                    let identifier = state.topoData.components[i].identifier
                    if (state.selectedComponentMap[identifier] !== undefined) {
                        keys.push(i)
                    }
                }
                // 排序
                keys.sort((a, b) => {
                    return a - b
                })
                // 逆向循环删除
                for (let i = keys.length - 1; i >= 0; i--) {
                    state.topoData.components.splice(keys[i], 1)
                }
                break
            case 'move':
                var dx = command.dx
                var dy = command.dy
                for (var key in command.items) {
                    let component = command.items[key]
                    component.style.position.x = component.style.position.x + dx
                    component.style.position.y = component.style.position.y + dy
                }
                break
            case 'copy-add':
                debugger
                this.commit('topoEditor/clearSelectedComponent')
                // var fuid = uid
                for (let i = 0; i < command.items.length; i++) {
                    var t = command.items[i]
                    let component = deepCopy(t)
                    // component.identifier = fuid()
                    component.name = component.type + state.topoData.components.length
                    component.style.visible = true
                    // 这里应该根据选中的的组件确定位置-暂时用个数
                    component.style.position.x = component.style.position.x + 25 * (state.copyCount + 1)
                    component.style.position.y = component.style.position.y + 25 * (state.copyCount + 1)
                    state.topoData.components.push(component)
                    this.commit('topoEditor/addSelectedComponent', component)
                    this.commit('topoEditor/increaseCopyCount')
                }
                break
            default:
                console.warn('不支持的命令.')
                break
        }
        // 记录操作
        state.undoStack.push(command)
    },
    /**
     * @description: 将一个组件从已选中当中移除
     * @param {*} component
     */
    removeSelectedComponent(state, component) {
        if (!component.identifier) return
        var index = -1
        for (var i = 0; i < state.selectedComponents.length; i++) {
            if (state.selectedComponents[i] === component.identifier) {
                index = i
                break
            }
        }
        if (index > -1) {
            state.selectedComponents.splice(index, 1)
        }
        Vue.delete(state.selectedComponentMap, component.identifier)
        // 如果移除的是选中组件
        if (state.selectedComponent != null && component.identifier === state.selectedComponent.identifier) {
            Vue.set(state, 'selectedComponent', null)
        }
        // 如果只有一个组件，则默认选中
        if (state.selectedComponents.length === 1) {
            var _component = state.selectedComponentMap[state.selectedComponents[0]]
            Vue.set(state, 'selectedComponent', _component)
        }
    },
    /**
     * @description: 设置选中数据
     * @param {*} selected
     */
    setLayerSelected(state, selected) {
        state.selectedIsLayer = selected
    },
    /**
     * @description: 选中的组件添加到选中数组中
     * @param {*} component
     */
    setSelectedComponent(state, component) {
        // 如果没有ID 给他添加一个ID
        if (!component.identifier) {
            component.identifier = Math.round(Math.random() * 10)
        }
        state.selectedComponents = [component.identifier]
        state.selectedComponentMap = {}
        // Vue.set() 参数一 为更改对象 , 参数二 需要更改的值 , 参数三 重新赋的值
        Vue.set(state.selectedComponentMap, component.identifier, component)
        Vue.set(state, 'selectedComponent', component)
    },
    /**
     * @description: 修改画布大小值selectedValue
     */
    setMainSize(state, Num) {
        state.selectedValue = Num
    }
}

const actions = {
    /**
     * @description:
     * @param {*} ctx
     * @return {*}
     */
    loadDefaultTopoData(ctx) {
        ctx.state.topoData = jsonData
    }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}
